package com.ttx.zookeeper.pubsub.curator;

import com.ttx.zookeeper.pubsub.curator.models.Instance;
import org.apache.curator.framework.api.transaction.CuratorOp;
import org.apache.curator.x.async.AsyncCuratorFramework;
import org.apache.curator.x.async.modeled.ModeledFramework;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author TimFruit
 * @date 20-2-28 下午7:54
 */
public class Publisher {
    private final Logger log = LoggerFactory.getLogger(getClass());
    private final AsyncCuratorFramework client;

    public Publisher(AsyncCuratorFramework client) {
        this.client = Objects.requireNonNull(client, "client cannot be null");
    }

    /**
     * Publish the given instance using the Instance client template
     *
     * @param instance instance to publish
     */
    public void publishInstance(Instance instance) {
        ModeledFramework<Instance> resolvedClient = Clients.instanceClient.resolved(client, instance.getType());
        resolvedClient.set(instance).exceptionally(e -> {
            log.error("Could not publish instance: " + instance, e);
            return null;
        });
    }

    /**
     * Publish the given instances using the Instance client template in a transaction
     *
     * @param instances instances to publish
     */
    public void publishInstances(List<Instance> instances) {
        List<CuratorOp> operations = instances.stream()
                .map(instance -> Clients.instanceClient
                        .resolved(client, instance.getType())
                        .createOp(instance)
//                        .set(instance)
                )
                .collect(Collectors.toList());
        client.transaction().forOperations(operations).exceptionally(e -> {
            log.error("Could not publish instances: " + instances, e);
            return null;
        });
    }
}
